#!/usr/bin/env python
# Re implementation of desktop-effects in pyglade
# and compizconfig-python
# Author(s): KageSenshi
#

import gtk
import gtk.glade
import sys
import gconf
import os
import compizconfig
import subprocess
import commands
from time import sleep

context=compizconfig.Context()
context.Read()
WINDOW_MANAGER_KEY='/apps/gnome-session/rh/window_manager'
decorator='gtk-window-decorator --replace'

xml = gtk.glade.XML("/usr/share/compiz/desktop-effects.glade")
# xml = gtk.glade.XML("desktop-effects.glade")

################### Compiz Launcher #######################
### codes borrowed*cough*stolen*cough* from fusion-icon ###
# Author(s): crdlb

fglrx_locations = ('/usr/lib/fglrx/libGL.so.1.2','/usr/lib/fglrx/libGL.so.1.2.xlibmesa', '/opt/mesa-xgl/lib/libGL.so.1.2')
gwd = 'gtk-window-decorator --replace'
xvinfo = commands.getoutput('xvinfo 2>/dev/null')
xdpyinfo = commands.getoutput('xdpyinfo 2>/dev/null')
glxinfo = commands.getoutput('glxinfo 2>/dev/null')

def env_intel():
    'Determines if we are using intel'

    if xvinfo.count('Intel') > 0:
        print '* Intel found, exporting: INTEL_BATCH=1'
        os.environ['INTEL_BATCH'] = '1'

def env_fglrx():
    'Determines if we are using fglrx'
    
    if xdpyinfo.count('FGLRX'):
        for location in fglrx_locations:
            if os.path.exists(location):
                print '* fglrx found, exporting: LD_PRELOAD=' + location
                os.environ['LD_PRELOAD'] = location
                break

def env_nvidia():
    'Determines if we are using nvidia'

    if xdpyinfo.count('NV-GLX') > 0:
        print '* nvidia found, exporting: __GL_YIELD="NOTHING" '
        os.environ['__GL_YIELD'] = 'NOTHING'
    
def set_env():
    #Trigger all environment checks
    env_intel()
    env_fglrx()
    env_nvidia()

def start_compiz():
    compiz = '/usr/bin/compiz'
    decoplugin=context.Plugins['decoration']
    decosetting=decoplugin.Display['command']
    if decosetting.Value != "emerald --replace":
        decosetting.Value = gwd
        context.Write()
    compiz_command = [compiz, '--replace', '--sm-disable', '--ignore-desktop-hints', 'ccp']

    if os.system('pgrep Xgl') == 0:
        compiz_command.append('--direct-rendering')
    
    #do it!
    print "* Executing:", ' '.join(compiz_command)
    set_env()
    return subprocess.Popen(compiz_command)


################ EOF Compiz launcher ######################                              


## timeout dialog ##

timeout_dialog = xml.get_widget('timeout_dialog')
timer_label = xml.get_widget('timer_label')

timeout_dialog.is_visible = False # I couldnt find any attribute for this in Gtk.Dialog? .. some help?

class TimerData:
    def __init__(self):
        self.timer, self.endtime = 0, 30

def start_metacity():
    run_wm = 'metacity --replace'
    subprocess.Popen(run_wm, shell=True)

def cancel_compiz(widget):
    enable_togglebutton.set_active(False)
    timeout_dialog.hide()
    timeout_dialog.is_visible = False

def save_settings(widget):
    gconfclient.set_string(WINDOW_MANAGER_KEY,'compiz')
    timeout_dialog.hide()
    timeout_dialog.is_visible = False

def on_timeout_dialog_close(widget,arg2):
    widget.hide()
    timeout_dialog.is_visible = False
    print arg2
    return True

def update_timer_label(timerdata):
    if timeout_dialog.is_visible and (timerdata.timer < timerdata.endtime):
        timerdata.timer = timerdata.timer + 1
        newlabel = "Testing the new settings. If you don't respond in %s second the previous settings will be restored." % (timerdata.endtime - timerdata.timer)
        timer_label.set_label(newlabel)
        return True
    elif not (timerdata.timer < timerdata.endtime):
        enable_togglebutton.set_active(False)
        timeout_dialog.hide()
        timeout_dialog.is_visible = False
        return False
    else: return False

## EOF timeout dialog ##


## main dialog ##
def gtk_main_quit(widget):
    sys.exit(0)


def on_cube_checkbox_toggled(widget):
    context.Read()
    context.ProcessEvents()
    if cube_checkbox.get_active():
       context.Plugins['cube'].Enabled = True
       context.Plugins['rotate'].Enabled = True
    else:
       context.Plugins['rotate'].Enabled = False
       context.Plugins['cube'].Enabled = False 
       # Bug?. For some reasons, cube is still loaded
    context.Write()

def on_enable_togglebutton_toggled(widget):
    print widget.get_active()
    if widget.get_active() == False:
       if os.system('pgrep compiz') == 0:
          start_metacity()
       if gconfclient.get_string(WINDOW_MANAGER_KEY) == 'compiz': 
          gconfclient.set_string(WINDOW_MANAGER_KEY,'metacity')
       wobble_checkbox.set_sensitive(False)
       cube_checkbox.set_sensitive(False)
    else:
       wobble_checkbox.set_sensitive(True)
       cube_checkbox.set_sensitive(True)
       process = start_compiz()
       procpoll = None
       for i in range(0,5):
           sleep(1)
           procpoll = process.poll()
       if not procpoll:
           timeout_dialog.show()
           timeout_dialog.is_visible = True
           timerdata = TimerData()
           timer_label.set_label("Testing the new settings. If you don't respond in %s second the previous settings will be restored." % (timerdata.endtime))
           gtk.timeout_add(1000, update_timer_label,timerdata)
       else:
           dialog = gtk.MessageDialog(xml.get_widget('dialog'), gtk.DIALOG_DESTROY_WITH_PARENT,
           gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "Desktop effects could not be enabled")
           dialog.run()
           dialog.destroy()

def on_wobble_checkbox_toggled(widget):
    context.Read()
    context.ProcessEvents()
    if wobble_checkbox.get_active(): context.Plugins['wobbly'].Enabled = True
    else: context.Plugins['wobbly'].Enabled = False
    context.Write()


# main program

enable_togglebutton = xml.get_widget('enable_togglebutton')
cube_checkbox = xml.get_widget('cube_checkbox')
wobble_checkbox = xml.get_widget('wobble_checkbox')



gconfclient = gconf.client_get_default ()
startup_enabled=False

if gconfclient.get_string(WINDOW_MANAGER_KEY) == 'compiz':
   startup_enabled = True


if not startup_enabled:
   enable_togglebutton.set_active(False)
   cube_checkbox.set_sensitive(False)
   wobble_checkbox.set_sensitive(False)
else:
   enable_togglebutton.set_active(True)

if context.Plugins['rotate'].Enabled and context.Plugins['cube'].Enabled: cube_checkbox.set_active(True)
if context.Plugins['wobbly'].Enabled: wobble_checkbox.set_active(True)

signaldict={
  'on_cube_checkbox_toggled' : on_cube_checkbox_toggled,
  'on_enable_togglebutton_toggled' : on_enable_togglebutton_toggled,
  'on_wobble_checkbox_toggled' : on_wobble_checkbox_toggled,
  'gtk_main_quit' : gtk_main_quit,
  'on_timeout_dialog_close' : on_timeout_dialog_close,
  'cancel_compiz' : cancel_compiz,
  'save_settings' : save_settings,
}
xml.signal_autoconnect(signaldict)

gtk.main()

